package com.dandelion.business.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.dandelion.business.entity.vo.LoginUserDetail;
import com.dandelion.business.entity.SysMenu;
import com.dandelion.business.entity.SysUser;
import com.dandelion.business.entity.vo.login.resp.Menu;
import com.dandelion.framework.enums.CodeEnum;
import com.dandelion.business.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;


/**
 * 用户详细服务impl
 *
 * @author 77088
 * @date 2021/12/25
 */
@Service
@Slf4j
public class UserDetailServiceImpl implements UserDetailsService {

    /**
     * 用户服务
     */
    @Autowired
    private ISysUserService userService;


    /**
     * 加载用户用户名
     *
     * @param username 用户名
     * @return {@link UserDetails}
     * @throws UsernameNotFoundException 用户名没有发现异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //查询用户信息
        SysUser sysUser = userService.loadUserByUsername(username);
        if (sysUser == null) {
            throw new UsernameNotFoundException(CodeEnum.UNAUTHORIZED.getMsg());
        }
        //查询授权信息
        ArrayList<SysMenu> sysMenus = userService.queryPerms(sysUser.getId());
        ArrayList<String> list = new ArrayList<>();
        for (SysMenu menu : sysMenus) {
            String perms = menu.getPerms();
            list.add(perms);
        }
        ArrayList<Menu> menus = handleMenu(sysMenus);
        return new LoginUserDetail(sysUser, menus, list);
    }

    private ArrayList<Menu> handleMenu(ArrayList<SysMenu> sysMenus) {
        ArrayList<Menu> topMenus = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            if (sysMenu.getPid() == 0) {
                Menu menu = new Menu();
                BeanUtil.copyProperties(sysMenu, menu);
                menu.setChilds(handleChild(sysMenus, sysMenu.getId()));
                topMenus.add(menu);
            }
        }
        topMenus.sort(Comparator.comparingInt(Menu::getSort));
        return topMenus;
    }

    private List<Menu> handleChild(ArrayList<SysMenu> sysMenus, Long pid) {
        ArrayList<Menu> topMenus = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            if (pid.intValue() == sysMenu.getPid()) {
                Menu menu = new Menu();
                BeanUtil.copyProperties(sysMenu, menu);
                menu.setChilds(handleChild(sysMenus, sysMenu.getId()));
                topMenus.add(menu);
            }
        }
        if (topMenus.isEmpty()) {
            return null;
        }
        topMenus.sort(Comparator.comparingInt(Menu::getSort));
        return topMenus;
    }
}
